using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MauiApp.Models;
using MauiApp.Services;
using MauiApp.Views;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Storage;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace MauiApp.ViewModels
{
    public partial class MainViewModel : ObservableObject
    {
        private readonly IApiService _apiService;
        private readonly FtpUploadService _ftpUploadService;
        [ObservableProperty]
        public DateTime openTime=DateTime.Now;
        [ObservableProperty]
        private ObservableCollection<TypesModel> fileTypes = new();
        [ObservableProperty]
        private TypesModel selectedFileType;
        [ObservableProperty]
        private ObservableCollection<TimeStampModel> currentFileTime = new();

        // 提供给页面调试使用：返回当前集合数量
        public int GetCurrentFileCount()
        {
            LogHelper.Debug($"[调试] CurrentFileTime集合当前数量: {CurrentFileTime.Count}");
            return CurrentFileTime.Count;
        }

        public MainViewModel(IApiService apiService)
        {
            _apiService = apiService;
            _ftpUploadService = new FtpUploadService(apiService);
        }
        public MainViewModel()
        {
            _apiService = new ApiService();
            _ftpUploadService = new FtpUploadService(_apiService);
            InitializeAsync();
        }

        [RelayCommand]
        public async Task InitializeAsync()
        {
            await InitializeFileTypesAsync();
            await UpdateViewAsync();
        }
        
        // 初始化文件类型
        private async Task InitializeFileTypesAsync()
        {
            try
            {
                LogHelper.Debug("开始初始化文件类型...");
                
                // 获取当前登录的用户名和用户ID
                string username = _apiService.GetCurrentUsername();
                string userId = _apiService.GetCurrentUserId();
                List<TypesModel> fileTypesList;
                
                // 优先使用用户ID（如果有效）
                if (!string.IsNullOrEmpty(userId) && int.TryParse(userId, out int parsedUserId))
                {
                    LogHelper.Debug($"根据用户ID '{userId}' 获取文件类型");
                    // 根据当前用户ID获取文件类型
                    fileTypesList = await _apiService.GetFileTypesByUserIdAsync(parsedUserId);
                }
                // 否则尝试使用用户名
                else if (!string.IsNullOrEmpty(username))
                {
                    LogHelper.Debug($"根据用户名 '{username}' 获取文件类型");
                    // 根据用户名获取文件类型
                    fileTypesList = await _apiService.GetFileTypesByUserAsync(username);
                }
                // 如果都无效，使用默认方式获取
                else
                {
                    LogHelper.Debug("未找到登录用户，使用默认方式获取文件类型");
                    // 使用默认方式获取文件类型（备用方案）
                    fileTypesList = await _apiService.GetFileTypesAsync();
                }
                
                LogHelper.Debug($"从API获取文件类型数量: {fileTypesList?.Count ?? 0}");
                
                FileTypes.Clear();
                if (fileTypesList != null && fileTypesList.Count > 0)
                {
                    foreach (var type in fileTypesList)
                    {
                        FileTypes.Add(type);
                        LogHelper.Debug($"添加文件类型: ID={type.FileTypeID}, Name={type.FileTypeName}, MemoryStrength={type.MemoryStrength}");
                    }
                    LogHelper.Debug($"成功添加所有文件类型，当前FileTypes集合数量: {FileTypes.Count}");
                }
                else
                {
                    LogHelper.Debug("获取到的文件类型列表为空");
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"初始化文件类型时发生错误: {ex.Message}");
                LogHelper.Error($"错误堆栈: {ex.StackTrace}");
                // 使用跨平台可写日志文件
                string logFilePath = LogHelper.LogFilePath;
                string? directoryPath = System.IO.Path.GetDirectoryName(logFilePath);
                if (!string.IsNullOrEmpty(directoryPath))
                {
                    System.IO.Directory.CreateDirectory(directoryPath);
                }
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 获取文件类型时发生异常: {ex.Message}\r\n");
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 内部异常: {ex.InnerException?.Message}\r\n");
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 堆栈跟踪: {ex.StackTrace}\r\n");
                
                // 显示错误消息
                var mainPage = Application.Current.Windows.FirstOrDefault()?.Page;
                if (mainPage != null)
                {
                    await mainPage.DisplayAlert(
                        "错误",
                        $"获取文件类型失败: {ex.Message}",
                        "确定");
                }
            }
        }

        [RelayCommand]
        public async Task UpdateViewAsync()
        {
            try
            {
                // 使用跨平台可写日志文件
                string logFilePath = LogHelper.LogFilePath;
                string? directoryPath = System.IO.Path.GetDirectoryName(logFilePath);
                if (!string.IsNullOrEmpty(directoryPath))
                {
                    System.IO.Directory.CreateDirectory(directoryPath);
                }
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 开始更新文件列表\r\n");
                
                // 创建一个新的集合来存储文件
                var newFileTimeList = new ObservableCollection<TimeStampModel>();
                
                // 获取当前登录的用户ID
                string userId = _apiService.GetCurrentUserId();
                List<TimeStampModel> files;
                
                // 确保用户ID有效（不为空且不是默认值）
                if (!string.IsNullOrEmpty(userId) )
                {
                    LogHelper.Debug($"根据用户ID '{userId}' 获取文件列表");
                    System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 根据用户ID '{userId}' 获取文件列表\r\n");
                    // 根据当前用户ID获取文件列表
                    files = await _apiService.GetFilesByUserAsync(userId);
                }
                // 如果用户ID无效，尝试使用App.CurrentUserId
                else if (!string.IsNullOrEmpty(App.CurrentUserId) && App.CurrentUserId != "0")
                {
                    userId = App.CurrentUserId;
                    LogHelper.Debug($"用户ID无效，回退使用App.CurrentUserId: {userId}");
                    System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 用户ID无效，回退使用App.CurrentUserId: {userId}\r\n");
                    files = await _apiService.GetFilesByUserAsync(userId);
                }
                else
                {
                    // 如果用户ID为空（不应该发生），获取当前登录的用户名
                    string username = _apiService.GetCurrentUsername();
                    if (!string.IsNullOrEmpty(username))
                    {
                        LogHelper.Debug($"用户ID为空，使用用户名 '{username}' 获取文件列表");
                        System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 用户ID为空，使用用户名 '{username}' 获取文件列表\r\n");
                        files = await _apiService.GetFilesByUserAsync(username);
                    }
                    else
                    {
                        // 如果用户名和用户ID都为空，返回空列表而不是获取所有文件
                        LogHelper.Error("用户名和用户ID都为空，无法获取文件列表");
                        System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 用户名和用户ID都为空，无法获取文件列表\r\n");
                        files = new List<TimeStampModel>();
                    }
                }
                
                if (files != null)
                {
                    System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 成功获取到文件数量: {files.Count}\r\n");
                    
                    foreach (var file in files)
                    {
                        System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 处理文件: {file.FileName}, FileID: {file.FileID}\r\n");
                        
                        // 获取复习信息（修复第2个问题）
                        try
                        {
                            // 根据文件ID获取所有时间戳记录
                            var reviewInfo = await _apiService.GetReviewInfoAsync(file.FileID);
                            int memoryCount = reviewInfo?.Timestamps?.Count ?? 0;
                            
                            // 根据文件类型ID从filetype表获取记忆强度
                            var fileType = await _apiService.GetFileTypeByIdAsync(file.TypeID);
                            double memoryStrength = fileType?.MemoryStrength ?? 1.0;
                            
                            // 计算下次复习时间
                            file.NextTime = CalculateNextReviewTime(file.Time, memoryCount, memoryStrength, 1.5, 0.9);
                            
                            System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 成功计算下次复习时间: {file.NextTime}, 时间戳数量: {memoryCount}, 记忆强度: {memoryStrength}\r\n");
                        }
                        catch (Exception ex)
                        {
                            System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 获取复习信息异常: {ex.Message}\r\n");
                            file.NextTime = DateTime.Now.AddDays(1); // 设置一个默认值
                        }
                        
                        newFileTimeList.Add(file);
                        System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 添加文件到临时集合，当前集合数量: {newFileTimeList.Count}\r\n");
                    }
                }
                else
                {
                    System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 获取到的文件列表为null\r\n");
                }

                // 先清空集合，然后按NextTime降序排序并添加，确保UI更新
                CurrentFileTime.Clear();
                if (newFileTimeList != null && newFileTimeList.Count > 0)
                {
                    // 按NextTime升序排序，时间最远的排在前面
                    var sortedList = newFileTimeList.OrderBy(item => item.NextTime).ToList();
                    foreach (var item in sortedList)
                    {
                        CurrentFileTime.Add(item);
                    }
                }
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 更新CurrentFileTime集合，当前数量: {CurrentFileTime.Count}\r\n");
                
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 更新文件列表完成\r\n");
            }
            catch (Exception ex)
            {
                // 使用跨平台可写日志文件
                string logFilePath = LogHelper.LogFilePath;
                string? dir = System.IO.Path.GetDirectoryName(logFilePath);
                if (!string.IsNullOrEmpty(dir)) System.IO.Directory.CreateDirectory(dir);
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 更新文件列表异常: {ex.Message}\r\n");
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 内部异常: {ex.InnerException?.Message}\r\n");
                System.IO.File.AppendAllText(logFilePath, $"[{DateTime.Now}] 堆栈跟踪: {ex.StackTrace}\r\n");
                
                // 显示错误消息
                var mainPage = Application.Current.Windows.FirstOrDefault()?.Page;
                if (mainPage != null)
                {
                    await mainPage.DisplayAlert(
                        "错误",
                        $"更新数据失败: {ex.Message}",
                        "确定");
                }
            }
        }
        
        [RelayCommand]
        public async Task<bool> AddFileAsync(TimeStampModel fileInfo)
        {
            try
            {
                // 通过API服务添加文件
                var success = await _apiService.AddFileAsync(fileInfo);
                
                if (success)
                {
                    // 重新加载数据
                    await UpdateViewAsync();
                    
                    // 计算下一次复习时间
                    var fileType = FileTypes.FirstOrDefault(t => t.FileTypeID == fileInfo.TypeID);
                    if (fileType != null)
                    {
                        fileInfo.NextTime = CalculateNextReviewTime(DateTime.Now, 1, fileType.MemoryStrength, 1.5, 0.9);
                    }
                }
                else
                {
                    // 显示错误消息
                    var mainPage = Application.Current.Windows.FirstOrDefault()?.Page;
                    if (mainPage != null)
                    {
                        await mainPage.DisplayAlert(
                            "错误",
                            "添加文件失败",
                            "确定");
                    }
                }
                
                return success;
            }
            catch (Exception ex)
            {
                string detailedErrorMessage = "选择并添加文件时出错: ";
                detailedErrorMessage += ex.Message;
                
                // 添加完整的错误信息到用户界面显示
                if (ex is WebException webEx && webEx.Response is FtpWebResponse ftpResponse)
                {
                    detailedErrorMessage += $"\nFTP错误状态码: {ftpResponse.StatusCode}";
                    detailedErrorMessage += $"\nFTP错误描述: {ftpResponse.StatusDescription}";
                }
                
                if (ex.InnerException != null)
                {
                    detailedErrorMessage += $"\n内部错误: {ex.InnerException.Message}";
                }
                
                // 同时输出到日志用于调试
                LogHelper.Error(detailedErrorMessage);
                
                // 在用户界面上显示完整的错误信息
                await Shell.Current.DisplayAlert("错误", detailedErrorMessage, "确定");
                
                return false;
            }
        }
        
        
        
        [RelayCommand]
        public async Task OpenFile(object param)
        {
            try
            {
                int fileId = param switch
                {
                    int i => i,
                    long l => checked((int)l),
                    string s when int.TryParse(s, out var v) => v,
                    TimeStampModel m => m.FileID,
                    _ => 0
                };

                if (fileId <= 0)
                {
                    await Shell.Current.DisplayAlert("错误", "未提供有效的文件ID", "确定");
                    return;
                }

                var fileInfo = await _apiService.GetFileByIdAsync(fileId);
                if (fileInfo == null)
                {
                    await Shell.Current.DisplayAlert("错误", $"未找到ID为{fileId}的文件", "确定");
                    return;
                }

                if (string.IsNullOrWhiteSpace(fileInfo.SavedPath) && string.IsNullOrWhiteSpace(fileInfo.FtpPath))
                {
                    await Shell.Current.DisplayAlert("错误", "文件没有可用的存储路径信息", "确定");
                    return;
                }

                string localCachePath = string.Empty;
                if (!string.IsNullOrWhiteSpace(fileInfo.SavedPath))
                {
                    var tempDir = Path.Combine(FileSystem.Current.AppDataDirectory, "TempFiles");
                    Directory.CreateDirectory(tempDir);
                    localCachePath = Path.Combine(tempDir, fileInfo.SavedPath);
                }

                bool isImage = IsImageExtension(Path.GetExtension(localCachePath));
                if (!string.IsNullOrWhiteSpace(localCachePath) && File.Exists(localCachePath) && isImage)
                {
                    await Shell.Current.GoToAsync($"//ImageViewerPage?FilePath={Uri.EscapeDataString(localCachePath)}");
                    openTime = DateTime.Now;
                    return;
                }

                if (!string.IsNullOrWhiteSpace(localCachePath) && File.Exists(localCachePath))
                {
#if WINDOWS
                    try
                    {
                        Process.Start(new ProcessStartInfo
                        {
                            FileName = localCachePath,
                            UseShellExecute = true
                        });
                        openTime = DateTime.Now;
                        return;
                    }
                    catch { }
#endif
                    var title = Path.GetFileName(localCachePath);
                    if (string.IsNullOrWhiteSpace(title)) title = "打开文件";
                    var request = new OpenFileRequest(title, new ReadOnlyFile(localCachePath));
                    await Launcher.OpenAsync(request);
                    openTime = DateTime.Now;
                    return;
                }

                if (!string.IsNullOrWhiteSpace(fileInfo.FtpPath))
                {
                    var fileDownloadInfo = new MauiApp.Services.FileInfo
                    {
                        FileId=fileInfo.Id,
                        FileName = fileInfo.FileName,
                        FilePath = fileInfo.SavedPath ?? string.Empty,
                        FileOwnerId = Preferences.Get("UserId", "")
                    };

                    var ftpCredentials = await _ftpUploadService.VerifyDownloadPermissionAsync(fileDownloadInfo);
                    if (ftpCredentials != null)
                    {
                        await Shell.Current.DisplayAlert("提示", "文件不存在本地缓存，正在从服务器下载...", "确定");

                        if (!string.IsNullOrWhiteSpace(localCachePath))
                        {
                            string tempFilePath = localCachePath;
                            bool downloadSuccess = await _ftpUploadService.DownloadFileFromFtpAsync(fileInfo.FtpPath, tempFilePath, ftpCredentials);

                            if (downloadSuccess && File.Exists(tempFilePath))
                            {
                                if (IsImageExtension(Path.GetExtension(tempFilePath)))
                                {
                                    await Shell.Current.GoToAsync($"//ImageViewerPage?FilePath={Uri.EscapeDataString(tempFilePath)}");
                                }
                                else
                                {
#if WINDOWS
                                    try
                                    {
                                        Process.Start(new ProcessStartInfo
                                        {
                                            FileName = tempFilePath,
                                            UseShellExecute = true
                                        });
                                    }
                                    catch { }
#else
                                    var title = Path.GetFileName(tempFilePath);
                                    if (string.IsNullOrWhiteSpace(title)) title = "打开文件";
                                    var request = new OpenFileRequest(title, new ReadOnlyFile(tempFilePath));
                                    await Launcher.OpenAsync(request);
#endif
                                }
                                openTime = DateTime.Now;
                            }
                            else
                            {
                                await Shell.Current.DisplayAlert("错误", "文件下载失败", "确定");
                            }
                        }
                        else
                        {
                            await Shell.Current.DisplayAlert("错误", "无效的本地缓存路径", "确定");
                        }
                    }
                    else
                    {
                        await Shell.Current.DisplayAlert("错误", "您没有权限下载此文件", "确定");
                    }
                }
                else
                {
                    await Shell.Current.DisplayAlert("错误", "文件没有存储路径信息", "确定");
                }
            }
            catch (Exception ex)
            {
                await Shell.Current.DisplayAlert("错误", $"打开文件发生错误: {ex.Message}", "确定");
            }
        }

        private static bool IsImageExtension(string? ext)
        {
            if (string.IsNullOrWhiteSpace(ext)) return false;
            ext = ext.ToLowerInvariant();
            return ext is ".jpg" or ".jpeg" or ".png" or ".gif" or ".bmp" or ".webp" or ".svg";
        }

        [RelayCommand]
        public async Task MarkFileAsRemembered(int FileId)
        {
            try
            {
                // 创建时间戳模型
                TimeStampModel timeStampModel = new TimeStampModel
                {
                    FileID = FileId,
                    Time = DateTime.Now,
                    OpenTime=openTime,
                    UserId = _apiService.GetCurrentUserId()
                };
                // 通过API服务添加时间戳标记为已记住
                var success = await _apiService.AddTimestampAsync(timeStampModel);
                
                if (success)
                {
                    // 重新加载数据
                    await UpdateViewAsync();
                    
                    // 显示成功消息
                    await Shell.Current.DisplayAlert(
                        "成功",
                        "文件已标记为记住",
                        "确定");
                }
                else
                {
                    // 显示错误消息
                    await Shell.Current.DisplayAlert(
                        "错误",
                        "标记文件为记住失败",
                        "确定");
                }
            }
            catch (Exception ex)
            {
                // 显示错误消息
                await Shell.Current.DisplayAlert(
                    "错误",
                    $"标记文件为记住时发生错误: {ex.Message}",
                    "确定");
            }
        }

        [RelayCommand]
        public async Task BrowseAndAddFile()
        {
            try
            {
                // 先校验必须选择文件类型
                if (SelectedFileType == null)
                {
                    await Shell.Current.DisplayAlert("提示", "请先选择文件类型", "确定");
                    return;
                }

                // 仅支持图片类型
                var imageFileType = new FilePickerFileType(
                    new Dictionary<DevicePlatform, IEnumerable<string>>
                    {
                        { DevicePlatform.Android, new[] { "image/*" } },
                        { DevicePlatform.iOS, new[] { "public.image" } },
                        { DevicePlatform.MacCatalyst, new[] { "public.image" } },
                        { DevicePlatform.WinUI, new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp" } },
                    }
                );

                var options = new PickOptions
                {
                    PickerTitle = "选择图片",
                    FileTypes = imageFileType,
                };

                var result = await FilePicker.Default.PickAsync(options);

                if (result != null)
                {
                    // 创建UploadInfo对象（使用Services命名空间的类，与FtpUploadService匹配）
                    // 使用App类中的静态全局用户信息
                    App.LogCurrentUserInfo("MainViewModel.CreateUploadInfo");
                    
                    var uploadInfo = new MauiApp.Models.UploadInfo
                    {
                        UserId = App.CurrentUserId, // 使用App类中的静态全局用户ID
                        FileName = result.FileName
                    };
                    
                    LogHelper.Debug($"传递给服务器的UserId: {uploadInfo.UserId}");

                    // 验证上传权限
                    var credentials = await _ftpUploadService.VerifyUploadPermissionAsync(uploadInfo);

                    if (credentials != null)
                    {
                        try
                        {
                            // 创建临时文件夹（如果不存在）
                            string tempFolderPath = Path.Combine(FileSystem.Current.AppDataDirectory, @"TempFiles");
                            if (!Directory.Exists(tempFolderPath))
                            {
                                Directory.CreateDirectory(tempFolderPath);
                            }

                            // 构建临时文件的完整路径
                            string newFileName = Guid.NewGuid().ToString() + Path.GetExtension(result.FileName);
                            string tempAbsFilePath = Path.Combine(tempFolderPath, newFileName);
                            string tempoRelFilePath = Path.Combine(newFileName); // 相对路径存储在数据库中
                            // 复制文件到临时文件夹用于即便用户删除文件，也能在缓存中找到。降低服务器流量
                            File.Copy(result.FullPath, tempAbsFilePath, true);
                            LogHelper.Debug($"文件已复制到临时文件夹: {tempAbsFilePath}");
                            
                            // 上传文件到FTP服务器，使用临时文件夹中的路径
                            string ftpPath = await _ftpUploadService.UploadFileToFtpAsync(
                                tempAbsFilePath,  // 使用临时文件的路径
                                credentials    // 凭证
                            );
                            
                          

                            if (!string.IsNullOrEmpty(ftpPath))
                            {
                                // 文件上传成功后，创建文件信息
                                var fileInfo = new TimeStampModel
                                {
                                    FileName = result.FileName,//呈现给用户看的文件名
                                    FilePath = tempoRelFilePath, // 构建文件路径，文件在缓存中的相对路径，当打开的时候直接从本地相对路径下寻找
                                    TypeID = SelectedFileType.FileTypeID, // 使用所选类型
                                    Time = DateTime.Now,
                                    OpenTime = DateTime.Now,
                                    FTPPath= ftpPath,
                                    UserId = App.CurrentUserId // 使用App类中的静态全局用户ID
                                };

                                // 调用API添加文件信息
                                var success = await _apiService.AddFileAsync(fileInfo);

                                if (success)
                                {
                                    // 添加成功后，更新文件列表
                                    await UpdateViewAsync();
                                    await Shell.Current.DisplayAlert("成功", "文件添加成功", "确定");
                                }
                                else
                                {
                                    await Shell.Current.DisplayAlert("失败", "文件信息添加失败", "确定");
                                }

                            }
                        }
                        catch (Exception copyEx)
                        {
                            LogHelper.Error($"复制文件到临时文件夹时出错: {copyEx.Message}");
                            await Shell.Current.DisplayAlert("错误", "准备上传文件时出错", "确定");
                        }
                    }
                    else
                    {
                        await Shell.Current.DisplayAlert("权限不足", "您没有足够的权限上传文件，请确认您的账户状态。", "确定");
                    }
                }
            }
            catch (Exception ex)
            {
                string detailedErrorMessage = "选择并添加文件时出错: ";
                detailedErrorMessage += ex.Message;
                
                // 添加完整的错误信息到用户界面显示
                if (ex is WebException webEx && webEx.Response is FtpWebResponse ftpResponse)
                {
                    detailedErrorMessage += $"\nFTP错误状态码: {ftpResponse.StatusCode}";
                    detailedErrorMessage += $"\nFTP错误描述: {ftpResponse.StatusDescription}";
                }
                
                if (ex.InnerException != null)
                {
                    detailedErrorMessage += $"\n内部错误: {ex.InnerException.Message}";
                }
                
                // 同时输出到控制台用于调试
                Console.WriteLine(detailedErrorMessage);
                
                // 在用户界面上显示完整的错误信息
                await Shell.Current.DisplayAlert("错误", detailedErrorMessage, "确定");
            }
        }

        /// <summary>
        /// 计算目标保留率对应的复习间隔（小时）
        /// </summary>
        /// <param name="targetRetention">目标保留率（0~1，如0.7表示70%）</param>
        /// <param name="memoryStrength">当前记忆强度S</param>
        /// <returns>间隔时间（小时）</returns>
        private double CalculateReviewInterval(double targetRetention, double memoryStrength)
        {
            if (targetRetention <= 0 || targetRetention >= 1)
                throw new ArgumentException("目标保留率必须在(0,1)之间", nameof(targetRetention));
            if (memoryStrength <= 0)
                throw new ArgumentException("记忆强度必须大于0", nameof(memoryStrength));

            // 公式：t = S * ln(1/R)
            return memoryStrength * Math.Log(1 / targetRetention);
        }

        /// <summary>
        /// 根据复习次数计算当前记忆强度
        /// </summary>
        /// <param name="reviewCount">复习次数（从1开始）</param>
        /// <returns>当前记忆强度S</returns>
        private double GetMemoryStrength(int reviewCount, double MemoryStrength, double reinforcementFactor = 1.5)
        {
            
            if (reviewCount < 1)
                throw new ArgumentException("复习次数不能小于1", nameof(reviewCount));

            // 公式：S(n) = S0 * k^(n-1)
            return MemoryStrength * Math.Pow(reinforcementFactor, reviewCount - 1);
        }

        /// <summary>
        /// 计算下次复习时间
        /// </summary>
        /// <param name="lastReviewTime">最近一次复习时间</param>
        /// <param name="reviewCount">当前是第几次复习（从1开始）</param>
        /// <param name="targetRetention">目标保留率（默认0.7，即70%）</param>
        /// <returns>下次复习时间</returns>
        public DateTime CalculateNextReviewTime(
            DateTime lastReviewTime,
            int reviewCount,
            double MemoryStrength,
            double reinforcementFactor = 1.5,
            double targetRetention = 0.7)
        {
            // 1. 获取当前记忆强度（随复习次数增强）
            double currentMemoryStrength = GetMemoryStrength(reviewCount, MemoryStrength, reinforcementFactor);
            //7 36 410.625
            //6 24 182.5
            // 2. 计算间隔时间（小时）
            double intervalHours = CalculateReviewInterval(targetRetention, currentMemoryStrength);
            //24 19.2
            // 3. 计算下次复习时间
            return lastReviewTime.AddHours(intervalHours);
        }

        [RelayCommand]
        public async Task UpdateTypesAsync()
        {
            try
            {
                // 获取当前登录的用户名
                string username = _apiService.GetCurrentUsername();
                List<TypesModel> types;
                
                if (string.IsNullOrEmpty(username))
                {
                    LogHelper.Debug("未找到登录用户，使用默认方式获取文件类型");
                    // 使用默认方式获取文件类型（备用方案）
                    types = await _apiService.GetFileTypesAsync();
                }
                else
                {
                    LogHelper.Debug($"根据用户名 '{username}' 获取文件类型");
                    // 根据当前用户ID获取文件类型
                    types = await _apiService.GetFileTypesByUserAsync(username);
                }
                
                if (types != null)
                {
                    FileTypes.Clear();
                    if (types != null)
                    {
                        foreach (var type in types)
                        {
                            FileTypes.Add(type);
                        }
                        LogHelper.Debug($"更新文件类型完成，当前数量: {FileTypes.Count}");
                    }
                }
            }
            catch (Exception ex)
            {
                // 处理异常
                var mainPage = Application.Current.Windows.FirstOrDefault()?.Page;
                if (mainPage != null)
                {
                    await mainPage.DisplayAlert(
                        "错误",
                        "更新文件类型失败: " + ex.Message,
                        "确定");
                }
            }
        }

        [RelayCommand]
        public async Task DeleteFile(TimeStampModel timeStampModel)
        {
            try
            {
                if (timeStampModel == null)
                    return;
                
                // 显示确认对话框
                var confirmResult = await Shell.Current.DisplayAlert(
                    "确认删除",
                    $"确定要删除 '{Path.GetFileName(timeStampModel.FilePath)}' 吗？",
                    "确定",
                    "取消");
                    
                if (!confirmResult) return;
                
                // 通过API服务删除文件
                bool success = await _apiService.DeleteFileAsync(timeStampModel.FileID);
                if (!success)
                {
                    await Shell.Current.DisplayAlert(
                        "错误",
                        "删除文件失败",
                        "确定");
                }
                else
                {
                    // 删除成功后从当前视图中移除相关项
                    var itemToRemove = CurrentFileTime.FirstOrDefault(item => item.FileID == timeStampModel.FileID);
                    if (itemToRemove != null)
                    {
                        CurrentFileTime.Remove(itemToRemove);
                    }
                    
                    // 显示成功消息
                    await Shell.Current.DisplayAlert(
                        "成功",
                        "文件已成功删除",
                        "确定");
                }
            }
            catch (Exception ex)
            {
                // 处理异常
                var mainPage = Application.Current?.Windows.FirstOrDefault()?.Page;
                if (mainPage != null)
                {
                    await mainPage.DisplayAlert(
                        "错误",
                        "删除文件时发生错误: " + ex.Message,
                        "确定");
                }
            }
        }
    }
}
